package net.imagine.backend.mockrmi.remote;

import java.lang.reflect.Proxy;

import net.imagine.backend.mockrmi.ProxyLookuper;
import net.imagine.backend.mockrmi.remote.client.ClientInvocationHandler;
import net.imagine.backend.mockrmi.remote.client.RequestSender;
import net.imagine.backend.mockrmi.util.MockRmiUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;

/**
 * ProxyLookuper远程实现类，通过TCP/IP方式调用
 * 
 * @author wuqh
 * @see ProxyLookuper
 */
public class RemoteProxyLookuper implements ProxyLookuper {
	protected static final Log logger = LogFactory.getLog(RemoteProxyLookuper.class);
	protected RequestSender sender;

	/**
	 * 设置sender对象
	 * 
	 * @param sender
	 */
	public void setSender(RequestSender sender) {
		this.sender = sender;
	}

	@Override
	public Object lookup(String uri) {
		return lookup(uri, Object.class);
	}

	@Override
	public Object lookup(String domain, int port, String id) {
		return lookup(domain, port, id, Object.class);
	}

	@Override
	public <T> T lookup(String uri, Class<T> clazz) {
		String[] result = MockRmiUtils.parseUri(uri);
		int port = MockRmiUtils.PORT;
		try {
			port = Integer.parseInt(result[1]);
		} catch (NumberFormatException e) {
			logger.debug("port not numeric,use default port" + MockRmiUtils.PORT, e);
		}
		return lookup(result[0], port, result[2], clazz);
	}

	@Override
	public <T> T lookup(String domain, int port, String id, Class<T> clazz) {
		Assert.notNull(sender, "sender cannot null in a remote lookuper");
		ClientInvocationHandler handler = new ClientInvocationHandler(domain, port, id, sender);
		return createProxy(clazz, handler);
	}

	/**
	 * 创建方法代理
	 * 
	 * @see Proxy
	 */
	@SuppressWarnings("unchecked")
	private <T> T createProxy(Class<T> clazz, ClientInvocationHandler handler) {
		return (T) Proxy.newProxyInstance(RemoteProxyLookuper.class.getClassLoader(), new Class[] { clazz }, handler);
	}

}
